package com.lalameow.serverlogingate.network.server;

import com.lalameow.serverlogingate.command.NetGateCommand;
import com.lalameow.serverlogingate.config.NetGateServerConfig;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.ssl.SslHandler;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Created with IntelliJ IDEA.
 * 创建人: 陈刚
 * 日期: 2018/3/1
 * 时间: 23:15
 * 功能：网关服务
 */
@Service
@Slf4j
public class NetGateServer {

    @Autowired
    private NetGateServerConfig netGateServerConfig;

    private ChannelFuture channelFuture=null;
    @Getter
    private NetGateState netGateState=NetGateState.START;
    private ServerSocketChannel serverSocketChannel;
    private EventLoopGroup bossGroup=null;
    private EventLoopGroup workerGroup=null;

    public void start(){

        try{
            bossGroup  =new NioEventLoopGroup();
            workerGroup=new NioEventLoopGroup();
            ServerBootstrap bootstrap=new ServerBootstrap();
            bootstrap.group(bossGroup,workerGroup);
            bootstrap.channel(NioServerSocketChannel.class);
            bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
            //通过NoDelay禁用Nagle,使消息立即发出去，不用等待到一定的数据量才发出去
//            bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
            //保持长连接状态
            bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
            bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    ChannelPipeline p = socketChannel.pipeline();
//                    p.addLast(new SslHandler());
                    p.addLast(new ObjectEncoder());
                    p.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
                    p.addLast(new NettyServerHandler());
                }
            });

            channelFuture= bootstrap.bind(netGateServerConfig.getServerIp(),netGateServerConfig.getServerPort()).sync();
            if(channelFuture.isSuccess()){
                log.info("登录网关启动成功！host:{},port:{}",netGateServerConfig.getServerIp(),netGateServerConfig.getServerPort());
                serverSocketChannel = (ServerSocketChannel) channelFuture.channel();
                netGateState=NetGateState.RUNNING;
                channelFuture.channel().closeFuture().sync();
            }


//
//           EventLoopGroup bossGroup = bossGroup = new NioEventLoopGroup();
//           EventLoopGroup workerGroup= workerGroup = new NioEventLoopGroup();
//            server = new ServerBootstrap();
//            server.group(bossGroup, workerGroup).
//                    channel(NioServerSocketChannel.class).
//                    childHandler(new NetGateChannelIniti()).
//                    option(ChannelOption.SO_BACKLOG,1024).
//                    childOption(ChannelOption.SO_KEEPALIVE, true);
//            channelFuture = server.bind(netGateServerConfig.getServerIp(),netGateServerConfig.getServerPort()).sync();
//            log.info("登录网关启动成功！");
//            netGateState=NetGateState.RUNNING;
//            channelFuture.channel().closeFuture().sync();
//            log.info("登录网关已经关闭！");
        }catch (InterruptedException e) {
            e.printStackTrace();
            log.info("登录网关启动失败！");
        }finally {
            if(workerGroup!=null)workerGroup.shutdownGracefully();
            if(bossGroup!=null)bossGroup.shutdownGracefully();
        }

    }
    public void stop(){
        if(workerGroup!=null)workerGroup.shutdownGracefully();
        if(bossGroup!=null)bossGroup.shutdownGracefully();
        if(serverSocketChannel!=null){
           serverSocketChannel.disconnect();
        }
        netGateState=NetGateState.STOP;
        log.info("停止登录网关");
    }
}
